﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using SGP;

namespace Sprite_Editor
{
    class Particle
    {
        public Particle(Emitter Owner)
        {
            this.emitter = Owner;
        }

        public void Initialize()
        {
            isactive = false;
            Random random = new Random(DateTime.Now.Millisecond);
            
            curcolor = emitter.InitialColor;
            startcolor = emitter.InitialColor;

            currotation = (float)(emitter.InitialRotation * Math.PI / 180);
            curscale = emitter.InitialScale;
            timealive = 0.0f;
            lifetime = (float)(random.NextDouble() * (emitter.LifetimeMax - emitter.LifetimeMin) + emitter.LifetimeMin);

            tVector2D direction = new tVector2D(0, 1);
            direction = tVector2D.Vector2DRotate(direction, (float)(((random.NextDouble() * ((emitter.EmitterRotation + emitter.AngleRange / 2) - (emitter.EmitterRotation - emitter.AngleRange / 2))) + (emitter.EmitterRotation - emitter.AngleRange / 2)) * Math.PI / 180));
            direction = tVector2D.Vector2DNormalize(direction);

            curvelocity = direction * (float)((random.NextDouble() * (emitter.InitialSpeedMax - emitter.InitialSpeedMin)) + emitter.InitialSpeedMin);

            rotationperupdate = (float)(((emitter.FinalRotation * Math.PI / 180) - (emitter.InitialRotation* Math.PI / 180)) / lifetime);
            scalechangeperupdate = (emitter.FinalScale - emitter.InitialScale) / lifetime;

            switch (emitter.Shape)
            {
                case EmitterShape.Line:
                    {
                        tVector2D center = new tVector2D(emitter.PosX, emitter.PosY);
                        tVector2D ParticlePreRotation = new tVector2D(((random.NextDouble() * ((emitter.PosX + emitter.OffsetX) - (emitter.PosX - emitter.OffsetX))) + (emitter.PosX - emitter.OffsetX)), emitter.PosY);
                        tVector2D CenterToParticle = new tVector2D(ParticlePreRotation.FX - center.FX, ParticlePreRotation.FY - center.FY);

                        float RotationInRadians = tVector2D.DegreesToRadians(emitter.EmitterRotation);

                        CenterToParticle = tVector2D.Vector2DRotate(CenterToParticle, RotationInRadians);

                        tVector2D ParticleAfterRotation = new tVector2D(center.FX + CenterToParticle.FX, center.FY + CenterToParticle.FY);

                        posX = ParticleAfterRotation.FX;
                        posY = ParticleAfterRotation.FY;

                        break;
                    }
                case EmitterShape.Square:
                    {
                        tVector2D center = new tVector2D(emitter.PosX, emitter.PosY);
                        tVector2D ParticlePreRotation = new tVector2D(((random.NextDouble() * ((emitter.PosX + emitter.OffsetX) - (emitter.PosX - emitter.OffsetX))) + (emitter.PosX - emitter.OffsetX)), ((random.NextDouble() * ((emitter.PosY + emitter.OffsetY) - (emitter.PosY - emitter.OffsetY))) + (emitter.PosY - emitter.OffsetY)));
                        tVector2D CenterToParticle = new tVector2D(ParticlePreRotation.FX - center.FX, ParticlePreRotation.FY - center.FY);

                        float RotationInRadians = tVector2D.DegreesToRadians(emitter.EmitterRotation);

                        CenterToParticle = tVector2D.Vector2DRotate(CenterToParticle, RotationInRadians);

                        tVector2D ParticleAfterRotation = new tVector2D(center.FX + CenterToParticle.FX, center.FY + CenterToParticle.FY);

                        posX = ParticleAfterRotation.FX;
                        posY = ParticleAfterRotation.FY;

                        break;
                    }
                case EmitterShape.Circle:
                    {
                        double randnumber = random.NextDouble();
                        posX = (float)(Math.Cos(randnumber) * emitter.OffsetX + emitter.PosX);
                        posY = (float)(Math.Sin(randnumber) * emitter.OffsetY + emitter.PosY);
                        break;
                    }
            }
        }

        public void Update(float deltaTime)
        {
            timealive += deltaTime;

            if (timealive > lifetime)
            {
                this.Initialize();
            }
            else
            {
                if (emitter.HasGravity)
                {
                         curvelocity.FY += .5f;
                }

                posX += curvelocity.FX * deltaTime;
                posY += curvelocity.FY * deltaTime;

                curscale += scalechangeperupdate * deltaTime;
                currotation += rotationperupdate * deltaTime;

                

                int aval = (int)(startcolor.A + ((emitter.FinalColor.A - startcolor.A) * (timealive / lifetime)));
                int rval = (int)(startcolor.R + ((emitter.FinalColor.R - startcolor.R) * (timealive / lifetime)));
                int gval = (int)(startcolor.G + ((emitter.FinalColor.G - startcolor.G) * (timealive / lifetime)));
                int bval = (int)(startcolor.B + ((emitter.FinalColor.B - startcolor.B) * (timealive / lifetime)));
                

                curcolor = Color.FromArgb(aval, rval, gval, bval);
            }
        }

        public void Render()
        {
            CSGP_TextureManager.GetInstance().Draw(TextureInfo.ID, (int)(posX - (TextureInfo.Width / 2)), (int)(posY - (TextureInfo.Height / 2)), curscale, curscale, new Rectangle(0, 0, TextureInfo.Width, TextureInfo.Height), TextureInfo.Width * curscale / 2, TextureInfo.Height * curscale / 2, currotation, curcolor);
        }

        private bool isactive;

        private float lifetime;
        private float rotationperupdate;
        private float scalechangeperupdate;

        public bool IsActive
        {
            get { return isactive; }
            set { isactive = value; }
        }

        private Emitter emitter;

        private float posX;

        public float PosX
        {
            get { return posX; }
            set { posX = value; }
        }

        private float posY;

        public float PosY
        {
            get { return posY; }
            set { posY = value; }
        }

        private tVector2D curvelocity;

        public tVector2D CurVelocity
        {
            get { return curvelocity; }
            set { curvelocity = value; }
        }

        private float currotation;

        public float CurRotation
        {
            get { return currotation; }
            set { currotation = value; }
        }

        private float curscale;

        public float CurScale
        {
            get { return curscale; }
            set { curscale = value; }
        }

        private float timealive;

        public float TimeAlive
        {
            get { return timealive; }
            set { timealive = value; }
        }

        private Color curcolor;

        public Color CurColor
        {
            get { return curcolor; }
            set { curcolor = value; }
        }

        private Color startcolor;
    }
}
